home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / gg / openssl-bin.lha / ssl / include / openssl / asn1_mac.h next >
Encoding:
C/C++ Source or Header  |  2002-08-08  |  18.5 KB  |  584 lines

  1. /* crypto/asn1/asn1_mac.h */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3.  * All rights reserved.
  4.  *
  5.  * This package is an SSL implementation written
  6.  * by Eric Young (eay@cryptsoft.com).
  7.  * The implementation was written so as to conform with Netscapes SSL.
  8.  * 
  9.  * This library is free for commercial and non-commercial use as long as
  10.  * the following conditions are aheared to.  The following conditions
  11.  * apply to all code found in this distribution, be it the RC4, RSA,
  12.  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  13.  * included with this distribution is covered by the same copyright terms
  14.  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15.  * 
  16.  * Copyright remains Eric Young's, and as such any Copyright notices in
  17.  * the code are not to be removed.
  18.  * If this package is used in a product, Eric Young should be given attribution
  19.  * as the author of the parts of the library used.
  20.  * This can be in the form of a textual message at program startup or
  21.  * in documentation (online or textual) provided with the package.
  22.  * 
  23.  * Redistribution and use in source and binary forms, with or without
  24.  * modification, are permitted provided that the following conditions
  25.  * are met:
  26.  * 1. Redistributions of source code must retain the copyright
  27.  *    notice, this list of conditions and the following disclaimer.
  28.  * 2. Redistributions in binary form must reproduce the above copyright
  29.  *    notice, this list of conditions and the following disclaimer in the
  30.  *    documentation and/or other materials provided with the distribution.
  31.  * 3. All advertising materials mentioning features or use of this software
  32.  *    must display the following acknowledgement:
  33.  *    "This product includes cryptographic software written by
  34.  *     Eric Young (eay@cryptsoft.com)"
  35.  *    The word 'cryptographic' can be left out if the rouines from the library
  36.  *    being used are not cryptographic related :-).
  37.  * 4. If you include any Windows specific code (or a derivative thereof) from 
  38.  *    the apps directory (application code) you must include an acknowledgement:
  39.  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40.  * 
  41.  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51.  * SUCH DAMAGE.
  52.  * 
  53.  * The licence and distribution terms for any publically available version or
  54.  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  55.  * copied and put under another distribution licence
  56.  * [including the GNU Public Licence.]
  57.  */
  58.  
  59. #ifndef HEADER_ASN1_MAC_H
  60. #define HEADER_ASN1_MAC_H
  61.  
  62. #include <openssl/asn1.h>
  63.  
  64. #ifdef  __cplusplus
  65. extern "C" {
  66. #endif
  67.  
  68. #ifndef ASN1_MAC_ERR_LIB
  69. #define ASN1_MAC_ERR_LIB    ERR_LIB_ASN1
  70. #endif 
  71.  
  72. #define ASN1_MAC_H_err(f,r,line) \
  73.     ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),ERR_file_name,(line))
  74.  
  75. #define M_ASN1_D2I_vars(a,type,func) \
  76.     ASN1_CTX c; \
  77.     type ret=NULL; \
  78.     \
  79.     c.pp=pp; \
  80.     c.q= *pp; \
  81.     c.error=ERR_R_NESTED_ASN1_ERROR; \
  82.     if ((a == NULL) || ((*a) == NULL)) \
  83.         { if ((ret=(type)func()) == NULL) \
  84.             { c.line=__LINE__; goto err; } } \
  85.     else    ret=(*a);
  86.  
  87. #define M_ASN1_D2I_Init() \
  88.     c.p= *pp; \
  89.     c.max=(length == 0)?0:(c.p+length);
  90.  
  91. #define M_ASN1_D2I_Finish_2(a) \
  92.     if (!asn1_Finish(&c)) \
  93.         { c.line=__LINE__; goto err; } \
  94.     *pp=c.p; \
  95.     if (a != NULL) (*a)=ret; \
  96.     return(ret);
  97.  
  98. #define M_ASN1_D2I_Finish(a,func,e) \
  99.     M_ASN1_D2I_Finish_2(a); \
  100. err:\
  101.     ASN1_MAC_H_err((e),c.error,c.line); \
  102.     asn1_add_error(*pp,(int)(c.q- *pp)); \
  103.     if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
  104.     return(NULL)
  105.  
  106. #define M_ASN1_D2I_start_sequence() \
  107.     if (!asn1_GetSequence(&c,&length)) \
  108.         { c.line=__LINE__; goto err; }
  109. /* Begin reading ASN1 without a surrounding sequence */
  110. #define M_ASN1_D2I_begin() \
  111.     c.slen = length;
  112.  
  113. /* End reading ASN1 with no check on length */
  114. #define M_ASN1_D2I_Finish_nolen(a, func, e) \
  115.     *pp=c.p; \
  116.     if (a != NULL) (*a)=ret; \
  117.     return(ret); \
  118. err:\
  119.     ASN1_MAC_H_err((e),c.error,c.line); \
  120.     asn1_add_error(*pp,(int)(c.q- *pp)); \
  121.     if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
  122.     return(NULL)
  123.  
  124. #define M_ASN1_D2I_end_sequence() \
  125.     (((c.inf&1) == 0)?(c.slen <= 0): \
  126.         (c.eos=ASN1_check_infinite_end(&c.p,c.slen)))
  127.  
  128. /* Don't use this with d2i_ASN1_BOOLEAN() */
  129. #define M_ASN1_D2I_get(b,func) \
  130.     c.q=c.p; \
  131.     if (func(&(b),&c.p,c.slen) == NULL) \
  132.         {c.line=__LINE__; goto err; } \
  133.     c.slen-=(c.p-c.q);
  134.  
  135. /* use this instead () */
  136. #define M_ASN1_D2I_get_int(b,func) \
  137.     c.q=c.p; \
  138.     if (func(&(b),&c.p,c.slen) < 0) \
  139.         {c.line=__LINE__; goto err; } \
  140.     c.slen-=(c.p-c.q);
  141.  
  142. #define M_ASN1_D2I_get_opt(b,func,type) \
  143.     if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
  144.         == (V_ASN1_UNIVERSAL|(type)))) \
  145.         { \
  146.         M_ASN1_D2I_get(b,func); \
  147.         }
  148.  
  149. #define M_ASN1_D2I_get_imp(b,func, type) \
  150.     M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
  151.     c.q=c.p; \
  152.     if (func(&(b),&c.p,c.slen) == NULL) \
  153.         {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
  154.     c.slen-=(c.p-c.q);\
  155.     M_ASN1_next_prev=_tmp;
  156.  
  157. #define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
  158.     if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
  159.         (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
  160.         { \
  161.         unsigned char _tmp = M_ASN1_next; \
  162.         M_ASN1_D2I_get_imp(b,func, type);\
  163.         }
  164.  
  165. #define M_ASN1_D2I_get_set(r,func,free_func) \
  166.         M_ASN1_D2I_get_imp_set(r,func,free_func, \
  167.             V_ASN1_SET,V_ASN1_UNIVERSAL);
  168.  
  169. #define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
  170.         M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
  171.             V_ASN1_SET,V_ASN1_UNIVERSAL);
  172.  
  173. #define M_ASN1_D2I_get_set_opt(r,func,free_func) \
  174.     if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
  175.         V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
  176.         { M_ASN1_D2I_get_set(r,func,free_func); }
  177.  
  178. #define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
  179.     if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
  180.         V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
  181.         { M_ASN1_D2I_get_set_type(type,r,func,free_func); }
  182.  
  183. #define M_ASN1_I2D_len_SET_opt(a,f) \
  184.     if ((a != NULL) && (sk_num(a) != 0)) \
  185.         M_ASN1_I2D_len_SET(a,f);
  186.  
  187. #define M_ASN1_I2D_put_SET_opt(a,f) \
  188.     if ((a != NULL) && (sk_num(a) != 0)) \
  189.         M_ASN1_I2D_put_SET(a,f);
  190.  
  191. #define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
  192.     if ((a != NULL) && (sk_num(a) != 0)) \
  193.         M_ASN1_I2D_put_SEQUENCE(a,f);
  194.  
  195. #define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
  196.     if ((a != NULL) && (sk_##type##_num(a) != 0)) \
  197.         M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
  198.  
  199. #define M_ASN1_I2D_put_SEQUENCE_opt_ex_type(type,a,f) \
  200.     if (a) M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
  201.  
  202. #define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
  203.     if ((c.slen != 0) && \
  204.         (M_ASN1_next == \
  205.         (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
  206.         { \
  207.         M_ASN1_D2I_get_imp_set(b,func,free_func,\
  208.             tag,V_ASN1_CONTEXT_SPECIFIC); \
  209.         }
  210.  
  211. #define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
  212.     if ((c.slen != 0) && \
  213.         (M_ASN1_next == \
  214.         (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
  215.         { \
  216.         M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
  217.             tag,V_ASN1_CONTEXT_SPECIFIC); \
  218.         }
  219.  
  220. #define M_ASN1_D2I_get_seq(r,func,free_func) \
  221.         M_ASN1_D2I_get_imp_set(r,func,free_func,\
  222.             V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
  223.  
  224. #define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
  225.         M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
  226.                         V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
  227.  
  228. #define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
  229.     if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
  230.         V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
  231.         { M_ASN1_D2I_get_seq(r,func,free_func); }
  232.  
  233. #define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
  234.     if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
  235.         V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
  236.         { M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
  237.  
  238. #define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
  239.         M_ASN1_D2I_get_imp_set(r,func,free_func,\
  240.             x,V_ASN1_CONTEXT_SPECIFIC);
  241.  
  242. #define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
  243.         M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
  244.             x,V_ASN1_CONTEXT_SPECIFIC);
  245.  
  246. #define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
  247.     c.q=c.p; \
  248.     if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
  249.         (void (*)())free_func,a,b) == NULL) \
  250.         { c.line=__LINE__; goto err; } \
  251.     c.slen-=(c.p-c.q);
  252.  
  253. #define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
  254.     c.q=c.p; \
  255.     if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
  256.                    free_func,a,b) == NULL) \
  257.         { c.line=__LINE__; goto err; } \
  258.     c.slen-=(c.p-c.q);
  259.  
  260. #define M_ASN1_D2I_get_set_strings(r,func,a,b) \
  261.     c.q=c.p; \
  262.     if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
  263.         { c.line=__LINE__; goto err; } \
  264.     c.slen-=(c.p-c.q);
  265.  
  266. #define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
  267.     if ((c.slen != 0L) && (M_ASN1_next == \
  268.         (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
  269.         { \
  270.         int Tinf,Ttag,Tclass; \
  271.         long Tlen; \
  272.         \
  273.         c.q=c.p; \
  274.         Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
  275.         if (Tinf & 0x80) \
  276.             { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
  277.             c.line=__LINE__; goto err; } \
  278.         if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
  279.                     Tlen = c.slen - (c.p - c.q) - 2; \
  280.         if (func(&(r),&c.p,Tlen) == NULL) \
  281.             { c.line=__LINE__; goto err; } \
  282.         if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
  283.             Tlen = c.slen - (c.p - c.q); \
  284.             if(!ASN1_check_infinite_end(&c.p, Tlen)) \
  285.                 { c.error=ERR_R_MISSING_ASN1_EOS; \
  286.                 c.line=__LINE__; goto err; } \
  287.         }\
  288.         c.slen-=(c.p-c.q); \
  289.         }
  290.  
  291. #define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
  292.     if ((c.slen != 0) && (M_ASN1_next == \
  293.         (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
  294.         { \
  295.         int Tinf,Ttag,Tclass; \
  296.         long Tlen; \
  297.         \
  298.         c.q=c.p; \
  299.         Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
  300.         if (Tinf & 0x80) \
  301.             { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
  302.             c.line=__LINE__; goto err; } \
  303.         if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
  304.                     Tlen = c.slen - (c.p - c.q) - 2; \
  305.         if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
  306.             (void (*)())free_func, \
  307.             b,V_ASN1_UNIVERSAL) == NULL) \
  308.             { c.line=__LINE__; goto err; } \
  309.         if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
  310.             Tlen = c.slen - (c.p - c.q); \
  311.             if(!ASN1_check_infinite_end(&c.p, Tlen)) \
  312.                 { c.error=ERR_R_MISSING_ASN1_EOS; \
  313.                 c.line=__LINE__; goto err; } \
  314.         }\
  315.         c.slen-=(c.p-c.q); \
  316.         }
  317.  
  318. #define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
  319.     if ((c.slen != 0) && (M_ASN1_next == \
  320.         (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
  321.         { \
  322.         int Tinf,Ttag,Tclass; \
  323.         long Tlen; \
  324.         \
  325.         c.q=c.p; \
  326.         Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
  327.         if (Tinf & 0x80) \
  328.             { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
  329.             c.line=__LINE__; goto err; } \
  330.         if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
  331.                     Tlen = c.slen - (c.p - c.q) - 2; \
  332.         if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
  333.             free_func,b,V_ASN1_UNIVERSAL) == NULL) \
  334.             { c.line=__LINE__; goto err; } \
  335.         if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
  336.             Tlen = c.slen - (c.p - c.q); \
  337.             if(!ASN1_check_infinite_end(&c.p, Tlen)) \
  338.                 { c.error=ERR_R_MISSING_ASN1_EOS; \
  339.                 c.line=__LINE__; goto err; } \
  340.         }\
  341.         c.slen-=(c.p-c.q); \
  342.         }
  343.  
  344. /* New macros */
  345. #define M_ASN1_New_Malloc(ret,type) \
  346.     if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
  347.         { c.line=__LINE__; goto err2; }
  348.  
  349. #define M_ASN1_New(arg,func) \
  350.     if (((arg)=func()) == NULL) return(NULL)
  351.  
  352. #define M_ASN1_New_Error(a) \
  353. /*    err:    ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
  354.         return(NULL);*/ \
  355.     err2:    ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
  356.         return(NULL)
  357.  
  358.  
  359. #define M_ASN1_next        (*c.p)
  360. #define M_ASN1_next_prev    (*c.q)
  361.  
  362. /*************************************************/
  363.  
  364. #define M_ASN1_I2D_vars(a)    int r=0,ret=0; \
  365.                 unsigned char *p; \
  366.                 if (a == NULL) return(0)
  367.  
  368. /* Length Macros */
  369. #define M_ASN1_I2D_len(a,f)    ret+=f(a,NULL)
  370. #define M_ASN1_I2D_len_IMP_opt(a,f)    if (a != NULL) M_ASN1_I2D_len(a,f)
  371.  
  372. #define M_ASN1_I2D_len_SET(a,f) \
  373.         ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
  374.  
  375. #define M_ASN1_I2D_len_SET_type(type,a,f) \
  376.         ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
  377.                         V_ASN1_UNIVERSAL,IS_SET);
  378.  
  379. #define M_ASN1_I2D_len_SEQUENCE(a,f) \
  380.         ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
  381.                   IS_SEQUENCE);
  382.  
  383. #define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
  384.         ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
  385.                         V_ASN1_UNIVERSAL,IS_SEQUENCE)
  386.  
  387. #define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
  388.         if ((a != NULL) && (sk_num(a) != 0)) \
  389.             M_ASN1_I2D_len_SEQUENCE(a,f);
  390.  
  391. #define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
  392.         if ((a != NULL) && (sk_##type##_num(a) != 0)) \
  393.             M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
  394.  
  395. #define M_ASN1_I2D_len_SEQUENCE_opt_ex_type(type,a,f) \
  396.         if (a) M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
  397.  
  398. #define M_ASN1_I2D_len_IMP_SET(a,f,x) \
  399.         ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
  400.  
  401. #define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
  402.         ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
  403.                         V_ASN1_CONTEXT_SPECIFIC,IS_SET);
  404.  
  405. #define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
  406.         if ((a != NULL) && (sk_num(a) != 0)) \
  407.             ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
  408.                       IS_SET);
  409.  
  410. #define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
  411.         if ((a != NULL) && (sk_##type##_num(a) != 0)) \
  412.             ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
  413.                            V_ASN1_CONTEXT_SPECIFIC,IS_SET);
  414.  
  415. #define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
  416.         ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
  417.                   IS_SEQUENCE);
  418.  
  419. #define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
  420.         if ((a != NULL) && (sk_num(a) != 0)) \
  421.             ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
  422.                       IS_SEQUENCE);
  423.  
  424. #define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
  425.         if ((a != NULL) && (sk_##type##_num(a) != 0)) \
  426.             ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
  427.                             V_ASN1_CONTEXT_SPECIFIC, \
  428.                             IS_SEQUENCE);
  429.  
  430. #define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
  431.         if (a != NULL)\
  432.             { \
  433.             v=f(a,NULL); \
  434.             ret+=ASN1_object_size(1,v,mtag); \
  435.             }
  436.  
  437. #define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
  438.         if ((a != NULL) && (sk_num(a) != 0))\
  439.             { \
  440.             v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
  441.             ret+=ASN1_object_size(1,v,mtag); \
  442.             }
  443.  
  444. #define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
  445.         if ((a != NULL) && (sk_num(a) != 0))\
  446.             { \
  447.             v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
  448.                        IS_SEQUENCE); \
  449.             ret+=ASN1_object_size(1,v,mtag); \
  450.             }
  451.  
  452. #define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
  453.         if ((a != NULL) && (sk_##type##_num(a) != 0))\
  454.             { \
  455.             v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
  456.                          V_ASN1_UNIVERSAL, \
  457.                          IS_SEQUENCE); \
  458.             ret+=ASN1_object_size(1,v,mtag); \
  459.             }
  460.  
  461. #define M_ASN1_I2D_len_EXP_SEQUENCE_opt_ex_type(type,a,f,mtag,tag,v) \
  462.         if (a)\
  463.             { \
  464.             v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
  465.                          V_ASN1_UNIVERSAL, \
  466.                          IS_SEQUENCE); \
  467.             ret+=ASN1_object_size(1,v,mtag); \
  468.             }
  469.  
  470. /* Put Macros */
  471. #define M_ASN1_I2D_put(a,f)    f(a,&p)
  472.  
  473. #define M_ASN1_I2D_put_IMP_opt(a,f,t)    \
  474.         if (a != NULL) \
  475.             { \
  476.             unsigned char *q=p; \
  477.             f(a,&p); \
  478.             *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
  479.             }
  480.  
  481. #define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
  482.             V_ASN1_UNIVERSAL,IS_SET)
  483. #define M_ASN1_I2D_put_SET_type(type,a,f) \
  484.      i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
  485. #define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
  486.             V_ASN1_CONTEXT_SPECIFIC,IS_SET)
  487. #define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
  488.      i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
  489. #define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
  490.             V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
  491.  
  492. #define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
  493.                          V_ASN1_UNIVERSAL,IS_SEQUENCE)
  494.  
  495. #define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
  496.      i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
  497.                 IS_SEQUENCE)
  498.  
  499. #define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
  500.         if ((a != NULL) && (sk_num(a) != 0)) \
  501.             M_ASN1_I2D_put_SEQUENCE(a,f);
  502.  
  503. #define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
  504.         if ((a != NULL) && (sk_num(a) != 0)) \
  505.             { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
  506.                        IS_SET); }
  507.  
  508. #define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
  509.         if ((a != NULL) && (sk_##type##_num(a) != 0)) \
  510.             { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
  511.                          V_ASN1_CONTEXT_SPECIFIC, \
  512.                          IS_SET); }
  513.  
  514. #define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
  515.         if ((a != NULL) && (sk_num(a) != 0)) \
  516.             { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
  517.                        IS_SEQUENCE); }
  518.  
  519. #define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
  520.         if ((a != NULL) && (sk_##type##_num(a) != 0)) \
  521.             { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
  522.                          V_ASN1_CONTEXT_SPECIFIC, \
  523.                          IS_SEQUENCE); }
  524.  
  525. #define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
  526.         if (a != NULL) \
  527.             { \
  528.             ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
  529.             f(a,&p); \
  530.             }
  531.  
  532. #define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
  533.         if ((a != NULL) && (sk_num(a) != 0)) \
  534.             { \
  535.             ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
  536.             i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
  537.             }
  538.  
  539. #define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
  540.         if ((a != NULL) && (sk_num(a) != 0)) \
  541.             { \
  542.             ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
  543.             i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
  544.             }
  545.  
  546. #define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
  547.         if ((a != NULL) && (sk_##type##_num(a) != 0)) \
  548.             { \
  549.             ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
  550.             i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
  551.                            IS_SEQUENCE); \
  552.             }
  553.  
  554. #define M_ASN1_I2D_put_EXP_SEQUENCE_opt_ex_type(type,a,f,mtag,tag,v) \
  555.         if (a) \
  556.             { \
  557.             ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
  558.             i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
  559.                            IS_SEQUENCE); \
  560.             }
  561.  
  562. #define M_ASN1_I2D_seq_total() \
  563.         r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
  564.         if (pp == NULL) return(r); \
  565.         p= *pp; \
  566.         ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
  567.  
  568. #define M_ASN1_I2D_INF_seq_start(tag,ctx) \
  569.         *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
  570.         *(p++)=0x80
  571.  
  572. #define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
  573.  
  574. #define M_ASN1_I2D_finish()    *pp=p; \
  575.                 return(r);
  576.  
  577. int asn1_GetSequence(ASN1_CTX *c, long *length);
  578. void asn1_add_error(unsigned char *address,int offset);
  579. #ifdef  __cplusplus
  580. }
  581. #endif
  582.  
  583. #endif
  584.